from rest_framework.views import exception_handler
from django.db import DatabaseError
from rest_framework.response import Response
import logging
from rest_framework import status
"""
def exception_handler(exc, context):
    #exc发生异常时的对象
    #context错误发生时的一些信息，执行上下文，字典形式存储信息 (导致异常的代码行、异常发生时的变量状态、调用栈等信息)
    if isinstance(exc, Http404):      #判断exc这个对象是否是Http404这个类的实例化对象
        exc = exceptions.NotFound()   #如果是的话就返回特定的结果
    elif isinstance(exc, PermissionDenied):
        exc = exceptions.PermissionDenied()

    if isinstance(exc, exceptions.APIException):
        headers = {}
        if getattr(exc, 'auth_header', None):
            headers['WWW-Authenticate'] = exc.auth_header
        if getattr(exc, 'wait', None):
            headers['Retry-After'] = '%d' % exc.wait

        if isinstance(exc.detail, (list, dict)):
            data = exc.detail
        else:
            data = {'detail': exc.detail}

        set_rollback()
        return Response(data, status=exc.status_code, headers=headers)

    return None
    
    #没有处理数据库以及其他的报错信息，只有处理django和drf的异常报错信息
"""

#创建日志记录器对象logger
logger = logging.getLogger("django")  #这里的django需要和日志配置中的名字对应起来

def custom_exception_handler(exc, context):
    """
    自定义的异常处理
    exc:本次请求发生的异常信息，也就四raise后面的
    context：本次请求发送异常的执行上下文（包括了本次请求的request对象，异常发送的时间，行号等）
    """
    response = exception_handler(exc, context)
    if response is None:
        """
        到这一步只有两种情况：
        1.要么程序没有出错
        2.要么是出错了django和drf不识别
        """
        view = context.get('view', None)
        if isinstance(exc, DatabaseError):  #判断是否是数据库异常
            """
            logger 实例的调用方法：
            logger.debug()
            logger.info()
            logger.warning()
            logger.error()
            logger.critical()
            还有两种其他的调用方法：
            logger.log()：手动输出一条指定日志级别的日志消息。
            logger.exception()：创建一个包含当前异常堆栈帧的 ERROR 级别日志消息。
            """
            logger.error('[%s] %s'%(view, exc))
            response = Response({"message":"服务器内部错误"},status=status.HTTP_507_INSUFFICIENT_STORAGE)
    return response


